/*
Kakine
ActionScript Framework
Copyright © 2011, PUNY, LLC.

This file is part of KAKINE.

KAKINE is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

KAKINE is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with KAKINE.  If not, see <http://www.gnu.org/licenses/>.
*/ 
package com.puny.ball.views.obstacles
{
	import com.puny.ball.utils.CollisionPA;
	import com.puny.ball.utils.Vector2D;
	import com.puny.mvc.helpers.IHelper;
	
	import flash.events.Event;
	import flash.geom.Rectangle;

	public class CirculerShapeObstacle extends Obstacle
	{
		private static const RADIAN:Number = Math.PI / 180;

		private const _center:Vector2D = new Vector2D();
		private const _pos:Vector2D = new Vector2D();
		private const _bars:Array = new Array();

		private var _bordered:Boolean;
		private var _radius:Number;
		private var _angles:Array;
		private var _r:Number
		
		private var _cpa:CollisionPA;
		private var _barH:Number;

		/**
		 * Its registration point must be at center of its shape.
		 * @param r radius of this shape. If it is <code>NaN</code>, longer one of width or height will be considered as its diameter.
		 * @param angles Array of angles (degree). It's considered open from the given smaller angle to the given bigger one. Closed shape in default.　From three o'clock, clockwise. 
		 * @param bordered if <code>true</code>, border lines between its center and its curve.
		 * @param w width for the border line.
		 * 
		 * <strong>Known Issue</strong>Depending on a speed of an object and this object curve, the object can go from insdie to outside.
		 */
		public function CirculerShapeObstacle(r:Number=NaN, angles:Array = null, bordered:Boolean = false, w:Number = 0) {
			var rect:Rectangle = getBounds(this);
			_center.x = x;
			_center.y = y;

			if (isNaN(r)) {
				_radius = rect.width > rect.height ? rect.width/2 : rect.height/2;
			} else {
				_radius = r;
			}

			_barH = w == 0 ? 1 : int(Math.abs(_radius * Math.sin(w * RADIAN))+1.5)*2;
			
			if (angles == null) {
				angles = [0,0];
			}
			
			_angles = [angles[0] * RADIAN, angles[1] * RADIAN];
			if (angles[0] != angles[1] && _bordered) {
				_bars.push(putBar(angles[0]));
				_bars.push(putBar(angles[1]));
			}
			
			_cpa = new CollisionPA(_center,_radius,_angles[0],_angles[1]);
			_cpa.rotation = rotation;
		}
		
		protected function get cpa():CollisionPA {
			return _cpa;
		}
//		protected function set bordered(value:Boolean):void {
//			_bordered = value;
//		}
		
		private function putBar(r:Number):RotatingBoxObstacle {
			var i:int = parent.getChildIndex(this);
			var box:RotatingBoxObstacle = new RotatingBoxObstacle();
//			trace("bar height", isNaN(_barH)? 1 : _barH);
			box.setRectangle(_radius+1, isNaN(_barH)? 1 : _barH);
			box.rotation = r;
			box.rotation = r;
			box.x = x;
			box.y = y;
			
			parent.addChildAt(box,i+1);
			return box;
		}		
	
		override protected function removedStageHandler(event:Event):void {
			for each(var ob:Obstacle in _bars) {
				container.removeChild(ob);
			}
			super.removedStageHandler(event);
		}
		override public function collision(org:Vector2D, dir:Vector2D):Boolean {
			pos = Infinity;
			var t:Number;
			if (_cpa.setParticle(org,dir)) {
				t = _cpa.collisionPoint();
				if (t < pos) {
					pos = t;
					newPos = _cpa.reflex();
					mirroredPos = _cpa.mirror();
				}
			}
			if (pos != Infinity) {
				_pos.x = org.x + pos * dir.x;
				_pos.y = org.y + pos * dir.y;
				hitPos = _pos;
			}
			return pos != Infinity;
		}
		
		public function inflate(r:Number):void {
			_r = _radius + r;
//			_cpa = new CollisionPA(_center,_r,_angles[0],_angles[1]);
			_cpa.radius = _r;
			drawDebugShape();			
		}
		override public function set rotation(value:Number):void {
			var w:Number = value - rotation;
			super.rotation = value;
			_cpa.rotation = rotation;
			for each(var ob:Obstacle in _bars) {
				ob.rotation += w;
			}
		}

		override protected function drawShape():void {
			shape.graphics.clear();
			shape.graphics.beginFill(0xFF0000,0.5);
			shape.graphics.drawCircle(x,y,_r);
			shape.graphics.endFill();
		}
		
		public function get center():Vector2D {
			return _center;
		}
		
		public function get radius():Number {
			return _radius;
		}
		
		public function get angles():Array {
			return _angles;
		}
		
	}
}